package ai.peanut.selfbase.common.security.shiro.session;


import ai.peanut.selfbase.common.redis.Redis;
import ai.peanut.selfbase.common.utils.Global;
import ai.peanut.selfbase.common.utils.Servlets;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;


public class SystemSessionDAO extends EnterpriseCacheSessionDAO {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private Redis redis;

    private static final String SESSION_PREFIX = "bms_session_prefix";

    public SystemSessionDAO() {
        super();
    }

    @Override
    protected void doUpdate(Session session) {
        if (session == null || session.getId() == null) {
            return;
        }

        HttpServletRequest request = Servlets.getRequest();
        if (request != null) {
            String uri = request.getServletPath();
            // 如果是静态文件，则不更新SESSION
            if (Servlets.isStaticFile(uri)) {
                return;
            }

        }
        redis.set(getKey(session.getId().toString()), session);
        redis.expire(getKey(session.getId().toString()), Global.getSessionTimeout().intValue()/1000) ;
        logger.info("会话信息更新 {} {}", session.getId(), request != null ? request.getRequestURI() : "");
    }

    @Override
    protected void doDelete(Session session) {
        if (session == null || session.getId() == null) {
            return;
        }
        logger.info("会话删除 {} ", session.getId());
        redis.del(getKey(session.getId().toString()));
    }

    @Override
    protected Serializable doCreate(Session session) {
        HttpServletRequest request = Servlets.getRequest();
        if (request != null) {
            String uri = request.getServletPath();
            // 如果是静态文件，则不创建SESSION
            if (Servlets.isStaticFile(uri)) {
                return null;
            }
        }
        super.doCreate(session);
        redis.set(getKey(session.getId().toString()), session);
        redis.expire(getKey(session.getId().toString()), Global.getSessionTimeout().intValue()/1000) ;
        logger.info("会话创建{} {}", session, request != null ? request.getRequestURI() : "");
        return session.getId();
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        Session session = null ;
        try {
            Object obj = redis.get(getKey(sessionId.toString()));
            if( obj == null ){
                return null ;
            }
            return  (Session)obj ;
        }catch(Exception e ) {
            logger.info("会话 redis异常获取对象转化异常：" , e);
            return null ;
        }

    }

    @Override
    public Session readSession(Serializable sessionId) throws UnknownSessionException {
        try {
            return this.doReadSession(sessionId);
        }catch ( Exception e ) {
            logger.info("++++++++++--------------" , e);
            throw new UnknownSessionException(e);
        }
    }

    @Override
    public Collection<Session> getActiveSessions() {
        logger.info("开始定时获取活动会话session");
        Set<Session> sessions = new HashSet<>();

        Set<String> keys = redis.keys(getKey("*"));
        if (keys != null && keys.size() > 0) {
            for (String key : keys) {
                Session s = (Session)redis.get(key);
                sessions.add(s);
            }
        }

        return sessions;
    }

    public String getKey(String keyStr) {
        return SESSION_PREFIX + keyStr;
    }


}
